package com.carb.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.carb.constant.MessageConstant;
import com.carb.dto.AnnouncementAddDTO;
import com.carb.dto.AnnouncementUpdateDTO;
import com.carb.entity.Announcement;
import com.carb.exception.EntityNotFoundException;
import com.carb.mapper.AnnouncementMapper;
import com.carb.service.IAnnouncementService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.carb.websocket.WebSocketServer;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 公告管理 服务实现类
 * </p>
 *
 * @author XuChaoyang
 * @since 2025-01-18
 */
@Service
public class AnnouncementServiceImpl extends ServiceImpl<AnnouncementMapper, Announcement> implements IAnnouncementService {

    @Resource
    private WebSocketServer webSocketServer;

    /**
     * 新增公告
     * @param announcementAddDTO 新增公告数据模型
     */
    @Override
    @Transactional
    public void addAnnouncement(AnnouncementAddDTO announcementAddDTO) {
        // 1、对象属性拷贝
        Announcement announcement = new Announcement();
        BeanUtils.copyProperties(announcementAddDTO, announcement);

        // 2、新增公告
        this.save(announcement);
        webSocketServer.sendToAllClients(JSON.toJSONString(announcement));
    }

    /**
     * 查询所有公告
     * @return 公告信息列表
     */
    @Override
    public List<Announcement> listAll() {
        return this.list(Wrappers.lambdaQuery(Announcement.class)
                .orderByDesc(Announcement::getCreateTime));
    }

    /**
     * 根据公告id查询公告信息
     * @param id 公告id
     * @return 查询结果
     */
    @Override
    public Announcement getAnnouncementById(Long id) {
        Announcement announcement = this.getById(id);
        if (announcement == null) {
            // 公告不存在
            throw new EntityNotFoundException(MessageConstant.ANNOUNCEMENT_NOT_FOUND);
        }
        return announcement;
    }

    /**
     * 修改公告信息
     * @param announcementUpdateDTO 修改的公告信息
     */
    @Override
    @Transactional
    public void updateAnnouncement(AnnouncementUpdateDTO announcementUpdateDTO) {
        // 1、获取更新属性
        // 1.1、公告id
        Long id = announcementUpdateDTO.getId();
        Announcement announcement = this.getById(id);
        if (announcement == null) {
            // 公告不存在
            throw new EntityNotFoundException(MessageConstant.ANNOUNCEMENT_NOT_FOUND);
        }
        if (announcement.getRelatedId() != null) {
            // 公告有关联ID，禁止更新
            throw new EntityNotFoundException(MessageConstant.ANNOUNCEMENT_HAS_RELATED_ID);
        }
        // 1.2、公告更新信息
        String title = announcementUpdateDTO.getTitle();
        String content = announcementUpdateDTO.getContent();

        // 2、公告更新
        this.update(new Announcement(), Wrappers.lambdaUpdate(Announcement.class)
                .eq(Announcement::getId, id)
                .set(title != null, Announcement::getTitle, title)
                .set(content != null, Announcement::getContent, content));
    }

    /**
     * 删除公告
     * @param id 公告id
     */
    @Override
    @Transactional
    public void deleteAnnouncement(Long id) {
        // 1、检查公告是否存在
        Announcement announcement = this.getById(id);
        if (announcement == null) {
            // 公告不存在
            throw new EntityNotFoundException(MessageConstant.ANNOUNCEMENT_NOT_FOUND);
        }
        if (announcement.getRelatedId() != null) {
            // 公告有关联ID，禁止删除
            throw new EntityNotFoundException(MessageConstant.ANNOUNCEMENT_HAS_RELATED_ID);
        }

        // 2、删除公告
        this.removeById(id);
    }

}
